﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

using CStock;
using NPlot;
using CTrading;
using CUtil;

using System.Collections;
using System.Diagnostics;



namespace CGraph
{
    public partial class ChartControl : Control, IDataPrividerGraph
    {
       
        #region members
        public delegate void InteractionHandler_Control(object sender, object axis);
        public delegate void InteractionHandler(object sender);
    


        private IChartWindow chartWindowParent;

		private NPlot.Windows.PlotSurface2D plotSurface;
		
		private bool plotChartQuotes;

		System.Collections.ArrayList plots;
		protected IProgramContext programContext;
		
		private System.Collections.ArrayList plotColors;
		IListQuotes quotes;
		
        
		private int chartNumber;
        private float penWidth;
        private float penWidthMarker;
       

        private System.Windows.Forms.ContextMenu contextMenu1;
        
        
        private EForms.MenuItem contextMenuProfile;

        
        DateTime xMin;
        DateTime xMax;
        ArrayList xValues;

        int indexStart;
        int indexStop;
    
       
        protected IDataItem dataItem;


	
		#endregion

		#region constructor, disposing
        public ChartControl()
        {
            try
            {
                InitializeComponent();
                InitializeCustom();

                penWidth = 1.0f;
                penWidthMarker = 1.0f;
                // This call is required by the Windows.Forms Form Designer.
                InitializeComponent();
                AddAllInteractions();

                this.plots = new ArrayList();
                plotColors = new ArrayList();
                plotColors.Add(System.Drawing.Color.Blue);
                plotColors.Add(System.Drawing.Color.Green);
                plotColors.Add(System.Drawing.Color.Red);
                //plotColors.Add(System.Drawing.Color.Pink);
                plotColors.Add(System.Drawing.Color.Violet);
                plotColors.Add(System.Drawing.Color.Sienna);
                plotColors.Add(System.Drawing.Color.Brown);
                plotColors.Add(System.Drawing.Color.Purple);
                plotColors.Add(System.Drawing.Color.Silver);
                plotColors.Add(System.Drawing.Color.Gold);
                plotColors.Add(System.Drawing.Color.Olive);


                chartNumber = 0;
            }
            catch (Exception ex)
            {
                Debug.Assert(false, "Error initializing ChartControl: " + ex.Message);
            }

        }


		
		

		#endregion

		#region IDataPrividerGraph

      
		public NPlot.Windows.PlotSurface2D PlotSurface
		{
			get
			{
				return this.plotSurface;
			}
			
		}
        public float PenWidth
        {
            get
            {
                return this.penWidth;
            }

        }
		public IProgramContext ProgramContext 
		{
			get
			{
				return this.programContext;
			}
			set
			{
				
			
				this.programContext = value;
			}
		}
      

        /// <summary>
        /// ProgramContext
        /// </summary>
        public IDataItem DataItem
        {
            get
            {
                return this.dataItem;
            }
            set
            {


                this.dataItem = value;
                
            }
        }
        /// <summary>
        /// ProgramContext
        /// </summary>
        public IChartWindow ChartWindow
        {
            get
            {
                return this.chartWindowParent;
            }
            set
            {


                this.chartWindowParent = value;
                
            }
        }	

		

		public bool IsPlottingChartQuotes 
		{
			get
			{
				return plotChartQuotes;
			}
			
			
		}
		public int ChartNumber 
		{
			get
			{
				return chartNumber;
			}
			set
			{
				chartNumber = value;
			}
			
			
		}
		
		public bool Intraday 
		{
			get
			{
				//Debug.Assert(this.programContext != null);
				if(this.programContext != null)
                    return this.programContext.Configuration.IntradayModus;
				return false;
			}

        }
        #region index and scroll
        public int IndexStart
		{
			get
			{
				return this.indexStart;
			}
			set
			{		
				this.indexStart = value;
                if(this.indexStart < 0)
                    this.indexStart = 0;
                //if(this.indexStart > this.indexStop)
                //    this.indexStart = indexStop;


			}
		}	
		public int IndexStop
		{
			get
			{
				return this.indexStop;
			}
			set
			{
				
			
				this.indexStop = value;
                if(this.indexStop > this.IndexMax)
                    this.indexStop = this.IndexMax;
                //if(this.indexStop < this.indexStart)
                //    this.indexStop = this.indexStart;

			}
		}	
		public int IndexMax
		{
			get
			{
				if(this.plots != null && this.plots.Count > 0)
				{

                    IPlot pl =  this.plots[0] as IPlot;
                    return this.xValues.Count;

				}
				else
				{
					return 0;
				}
				
			}
		
		}	
		private int XOverhead
		{
			get
			{
				
				int i = (this.indexStop - this.indexStart) / 30;
				if(i > 15)
					i = 15;
                //if(this.prognosisMode)
                //    i += 10;
				return i;

			}

        }
        #endregion


        public void PlotLegend()
		{
			try
			{
                Legend legend = new Legend();
                //legend.AttachTo(PlotSurface2D.XAxisPosition.Top, PlotSurface2D.YAxisPosition.Left);

                legend.AttachTo(PlotSurface2D.XAxisPosition.Top, PlotSurface2D.YAxisPosition.Left);
                legend.VerticalEdgePlacement = Legend.Placement.Inside;
                legend.BackgroundColor = System.Drawing.SystemColors.Control;
                legend.NumberItemsVertically = 1;
                
                if (this.chartNumber == 0)
                {
                    legend.HorizontalEdgePlacement = Legend.Placement.Outside;
                    legend.YOffset = 6;
                }
                else
                {
                    legend.HorizontalEdgePlacement = Legend.Placement.Inside;
                    legend.YOffset = 0;
                }
                legend.XOffset = 0; // note that these numbers can be negative.
                
                plotSurface.Legend = legend;
                plotSurface.Refresh();

               
			}
			catch(Exception exc)
			{
				Debug.Assert(false,"Error plotting legend", exc.Message);
			}


			

		}

		#endregion

        #region Plot interactions


        protected override void OnPaint(PaintEventArgs pe)
        {
            base.OnPaint(pe);
        }
        public void AddAllInteractions()
        {
            this.plotSurface.AddInteraction(new NPlot.Windows.PlotSurface2D.Interactions.HorizontalDrag());
            this.plotSurface.AddInteraction(new NPlot.Windows.PlotSurface2D.Interactions.VerticalDrag());
            this.plotSurface.AddInteraction(new NPlot.Windows.PlotSurface2D.Interactions.AxisDrag(true));
            this.plotSurface.InteractionOccured += new NPlot.Windows.PlotSurface2D.InteractionHandler(this.PlotInteractionOccured);

        }
        #endregion

        #region Implementation

        
        private void SynchronizeAllChartAxis(IChartWindow mycw)
        {
            ChartWindow cw = mycw as ChartWindow;
            DateTimeAxis axis = new DateTimeAxis(this.plotSurface.XAxis1);
            
            for (int i = 0; i < cw.Charts.Count; i++)
            {
                ChartControl c2 = cw.Charts[i] as ChartControl;
                if (c2 != this)
                {
                    if (c2.PlotSurface.XAxis1 != null)
                    {
                        string oldLabel = c2.PlotSurface.XAxis1.Label; 
                        bool oldHide = c2.PlotSurface.XAxis1.HideTickText;

                        axis.Label = oldLabel;
                        axis.HideTickText = oldHide;
                        if(this.chartNumber > 0)
                            axis.HideTickText = true;
                    }
                    c2.PlotSurface.XAxis1 = axis;
                    c2.PlotSurface.Refresh();
                }
            }
        }
        /// <summary>
        /// When the volumePS chart has changed, this is called which updates hte costPS chart.
        /// </summary>
        private void PlotInteractionOccured(object sender, object eventObject)
        {
            
            SynchronizeAllChartAxis(this.chartWindowParent);

        }
        #endregion

        #region Component Designer generated code
        /// <summary> 
		/// Required method for Designer support - do not modify 
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeCustom()
		{
			this.plotSurface = new NPlot.Windows.PlotSurface2D();
            
			this.contextMenu1 = new System.Windows.Forms.ContextMenu();
           
            this.contextMenuProfile = new EForms.MenuItem();
            
            
            
			this.SuspendLayout();
			// 
			// plotSurface
			// 
			//VersionChange this.plotSurface.AllowSelection = false;
			this.plotSurface.BackColor = System.Drawing.SystemColors.ControlLightLight;
			this.plotSurface.Dock = System.Windows.Forms.DockStyle.Fill;
		
			//this.plotSurface.Location = new System.Drawing.Point(0, 0);
			this.plotSurface.Name = "plotSurface";
			

            
			//this.plotSurface.Size = new System.Drawing.Size(368, 200);
			this.plotSurface.TabIndex = 0;
			this.plotSurface.Title = "";
			this.plotSurface.TitleFont = new System.Drawing.Font("Arial", 14F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Pixel);
			//VersionChange this.plotSurface.VerticalEdgeLegendPlacement = NPlot.Legend.Placement.Outside;
			this.plotSurface.XAxis1 = null;
			this.plotSurface.XAxis2 = null;
			this.plotSurface.YAxis1 = null;
			this.plotSurface.YAxis2 = null;

            this.plotSurface.Padding = 0;
            this.contextMenu1.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {contextMenuProfile });
		
            this.contextMenuProfile.Icon = null;
            this.contextMenuProfile.Index = 0;
            this.contextMenuProfile.OwnerDraw = true;
            this.contextMenuProfile.ShortcutText = "";
            this.contextMenuProfile.Text = "Change Chart Lines";
            this.contextMenuProfile.Click += new System.EventHandler(this.contextMenuProfile_Click);

			// 
			// ChartControl
			// 
			this.ContextMenu = this.contextMenu1;
			this.Controls.Add(this.plotSurface);
			this.Name = "ChartControl";
			this.Size = new System.Drawing.Size(368, 200);
			this.ResumeLayout(false);

		}
		#endregion




        /// <summary>
		/// This is called prior to volumePS refresh to enforce the WorldMin is 0. 
		/// This may have been changed by the axisdrag interaction.
		/// </summary>
		/// <param name="sender"></param>
		private void PreRefresh(object sender)
		{
			this.plotSurface.YAxis1.WorldMin = 0.0;
		}
     
		
        private bool ResetPlotSurface_New()
        {
            try
            {
                
                plotSurface.Clear();

                if (this.plots.Count < 1)
                {
                    plotSurface.Refresh();
                    return false;
                }
                this.PlotGrid();


                for (int i = 0; i < this.plots.Count; i++)
                {
                    IPlot pl = this.plots[i] as IPlot;
                    plotSurface.Add(pl);
                }
                return true;
            }
            catch (Exception ex)
            {
                Debug.Assert(false, "Error in ResetPlotSurface_New: " + ex.Message);
                return false;
            }


        }
        private bool SetPlotSurfaceProperties()
        {
            try
            {
                if (!ResetPlotSurface_New())
                    return false;

                Axis xOld = plotSurface.XAxis1;
                Debug.Assert(xOld != null, "No xAxis set in");
                if (xOld == null)
                    return false;
                Axis yOld = plotSurface.YAxis1;
                Debug.Assert(yOld != null, "No yAxis set in");
                if (yOld == null)
                    return false;


                plotSurface.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;

                if (xOld != null)
                    plotSurface.XAxis1 = xOld;
                

                if (yOld != null)
                    plotSurface.YAxis1 = yOld;

                
                IPlot pl = this.plots[0] as IPlot;
               

                //plotSurface.XAxis1.Label = "Date / Time";
               
                //plotSurface.YAxis1.Label = "Price";

                // make sure plot surface colors are as we expect - the wave example changes them.
                plotSurface.PlotBackColor = Color.White;
                plotSurface.BackColor = Color.White;
                plotSurface.XAxis1.Color = Color.Black;
                if (this.chartNumber > 0)
                    plotSurface.XAxis1.HideTickText = true;
                plotSurface.YAxis1.Color = Color.Black;

                return true;
            }
            catch (Exception ex)
            {
                Debug.Assert(false, "Error in SetPlotSurfaceProperties: " + ex.Message);
                return false;
            }
        }
        private bool Redraw()
        {
            try
            {
                AdjustChartLimits();

                if (!SetPlotSurfaceProperties())
                    return false;
                AddAllInteractions();
                
                PlotLegend();
                
                plotSurface.Refresh();
                
                this.programContext.Logfile.WriteTimeSpanLog("   end of redraw ");

                return true;
            }
            catch (Exception ex)
            {
                Debug.Assert(false, "Error redrawing chart: " + ex.Message);
                return false;
            }


        }
 
       private LinePlot Create_LinePlot(string name, System.Collections.ICollection dataCollection, bool indicator)
		{
            try
            {
                LinePlot lp ;
                int size = dataCollection.Count;

                if (size == 0)
                {
                    //implementation changed - should not happen!!!

                    IDataItem di = TradeEconomy.GetDataItemByID(name);
                    if (di != null)
                    {
                        QuoteUpdater qupdater = new QuoteUpdater(this.programContext);
                        if (qupdater.CheckUpdateShare(di))
                        {
                            System.Windows.Forms.MessageBox.Show("Quotes are updated - please close the window and reopen: " + name);
                        }
                        else
                        {
                            System.Windows.Forms.MessageBox.Show("The profile contains a share, but no data is available, so please first upload from web: " + name);
                       
                        }
                    }

                    System.Windows.Forms.MessageBox.Show("SW Error - data for this chart not available! - " + name);
                    
                    return null;
                }

               
                ArrayList yAxisArray = new ArrayList();
                ArrayList xAxisArray = new ArrayList();

                IList dataList = dataCollection as IList;

                for (int i = 0; i < size; i++)
                {
                    IQuoteBase qw = dataList[i] as IQuoteBase;

                    double val = qw.CLOSEc ;
                    yAxisArray.Add(val);

                    //dt = dt.AddDays(1);
                    xAxisArray.Add(qw.DATE);
                }

               
                lp = Create_LinePlot(yAxisArray, xAxisArray);
                //lp.Label = AdjustLabel(name);
                lp.Label = name;
                return lp;
            }
            catch (Exception ex)
            {
                Debug.Assert(false, ex.Message);
                return null;

            }
           
		}
       //private string AdjustLabel(string strLabel)
       //{
       //    int len = strLabel.Length;
       //    string strResult = "_";
       //    if (len > 17)
       //    {
       //        string strLeft = strLabel.Remove(7, len - 7);
       //        string strRight = strLabel.Remove(0, len - 10);
       //        strResult = strLeft + "..." + strRight;
       //    }
       //    else if (len < 16)
       //    {
       //        for (int i = 1; i < (16 - len); i++)
       //        {
       //            strResult += "_";
       //        }
       //        strResult = strResult + strLabel;
       //    }
       //    else
       //    {
       //        strResult = strLabel;
       //    }
       //    return strResult;
       //    //return strLabel;
       //}
        private LinePlot Create_LinePlot(IIndicator ind)
        {
            try
            {

                LinePlot lp ;
                
                ArrayList yAxisArray = new ArrayList();
                ArrayList xAxisArray = new ArrayList();

                IListQuotesBase indValues = ind.Values ;


                for (int i = 0; i < indValues.Count ; i++)
                {
                    //IQuoteBase qw = ind.DataClassQuotes[i] as IQuoteBase;
                    xAxisArray.Add(indValues[i].DATE);
                    yAxisArray.Add(indValues[i].CLOSEc);
       
                }
                
                lp = Create_LinePlot(yAxisArray, xAxisArray);
                lp.Label = ind.Name;
                return lp;
                   
            }
              
            
            catch (Exception ex)
            {
                Debug.Assert(false, ex.Message);
                return null;

            }

        }
        private LinePlot Create_LinePlot(ArrayList yAxisArray, ArrayList xAxisArray)
        {
            LinePlot lp = new LinePlot();
            lp.OrdinateData = yAxisArray;
            lp.AbscissaData = xAxisArray;

            lp.Color = (Color)plotColors[this.plots.Count] ;
            lp.Pen.Width = penWidth;
            GetXminXmax(lp);

            lp.Label = this.dataItem.DataClass.Name;

          
            return lp;
          

        }
	
        private void Set_X_Axis()
        {
            this.plotSurface.XAxis1.WorldMin =Convert.ToDouble(this.xMin.Ticks);
            this.plotSurface.XAxis1.WorldMax = Convert.ToDouble(this.xMax.Ticks);

        }
       
         private void GetXminXmax(LinePlot lp)
        {
            //lp.AbscissaData = xAxisArray;

            this.xValues = lp.AbscissaData as ArrayList;


            this.xMin = Convert.ToDateTime(xValues[0]);
            this.xMax = Convert.ToDateTime(xValues[xValues.Count - 1]);



            
        }

     
       
        private void GetXMinXMax(CandlePlot cp)
        {
            DataTable dt = cp.DataSource as DataTable;


            xValues = new ArrayList();
            for(int i = 0; i < dt.Rows.Count; i++)
            {
                DataRow dr = dt.Rows[i];
                xValues.Add((DateTime)dr[6]);

            
            }

            DataRow drNew = dt.Rows[0];
            System.DateTime timeMin = (DateTime)drNew[6];
            drNew = dt.Rows[dt.Rows.Count - 1];
            DateTime timeMax = Convert.ToDateTime(drNew[6]);
            this.xMin = timeMin;
            this.xMax = timeMax;
            
        }
        
   
        private bool AdjustYLinePlot(IPlot myPl)
        {

            LinePlot pl = myPl as LinePlot;

            
            if (this.dataItem.Show100PercentGraph)
            {
                ArrayList yAxisArray = pl.OrdinateData as ArrayList;
                pl.AdjustTo100PercentScale();
                //pl.OrdinateData = yAxisArray;
            }
            
            return true;

        }
        private bool AdjustChartLimits()
        {
            try
            {
                if (this.plots.Count < 1)
                    return false;

                for (int i = 0; i < this.plots.Count; i++)
                {
                    IPlot plLoop = this.plots[i] as IPlot;
                    Type typ = plLoop.GetType();
                    if (typ != typeof(PointPlot))
                    {
                        if (typ == typeof(CandlePlot))
                        {

                        }
                        else if (typ == typeof(LinePlot))
                        {
                            AdjustYLinePlot(plLoop);


                        }
                    }
                    
                }
                return true;



            }
            catch (Exception exc)
            {
                Debug.Assert(false, "Error adjusting limits ", exc.Message);
                return false;
            }

        }
        private void PlotGrid()
        {
            try
            {
                Pen majorGridPen = new Pen(Color.LightGray);
                float[] pattern = { 1.0f, 2.0f };
                majorGridPen.DashPattern = pattern;
                //plotSurface.MajorGridPen = majorGridPen;

                majorGridPen.DashPattern = pattern;

                plotSurface.Add(new Grid());
                //plotSurface.MinorGridPen = majorGridPen;
            }
            catch (Exception exc)
            {
                Debug.Assert(false, "Error plotting grid", exc.Message);
            }

        }

     
        private void RedrawAndScroll()
        {
            this.Redraw();
            if (this.chartWindowParent != null)
            {
                this.chartWindowParent.ScrollAllCharts(0, 0);
            }
            else
            {
                Debug.Assert(false, "Some error - parent window is not set...");
            }
        }
	
		public void ResetChart()
		{
            try
            {
                this.plots = new ArrayList();
                this.ResetLimits();
                plotSurface.Clear();
                plotSurface.Refresh();
            }
            catch (Exception ex)
            {
                Debug.Assert(false, "Error in context menu " + ex.Message);
            }
		}
	
	
	

        private DataTable DataTableFromQuotes(IList dataCollection)
        {
            DataTable dt = new DataTable();
            DataColumn dc = new DataColumn("Open", typeof(double));
            dt.Columns.Add(dc);
            dc = new DataColumn("Low", typeof(double));
            dt.Columns.Add(dc);
            dc = new DataColumn("High", typeof(double));
            dt.Columns.Add(dc);
            dc = new DataColumn("Close", typeof(double));
            dt.Columns.Add(dc);
            dc = new DataColumn("AdjClose", typeof(double));
            dt.Columns.Add(dc);
            dc = new DataColumn("Volume", typeof(long));
            dt.Columns.Add(dc);
            dc = new DataColumn("Date", typeof(DateTime));
            dt.Columns.Add(dc);

           

            for (int i = 0; i < dataCollection.Count; i++)
            {
                IQuote qw = dataCollection[i] as IQuote;
                DataRow newRow = dt.NewRow();
                newRow[6] = qw.DATE;


                newRow[0] = qw.OPENc ;
                newRow[1] = qw.LOW ;
                newRow[2] = qw.HIGH ;
                newRow[3] = qw.CLOSEc ;
                dt.Rows.Add(newRow);


            }
            return dt;

        }
        private CandlePlot Create_CandleStickPlot(IList dataCollection)
        {
            DataTable dt = this.DataTableFromQuotes(dataCollection);

            CandlePlot cp = new CandlePlot();
            cp.DataSource = dt;
            cp.AbscissaData = "Date";
            cp.OpenData = "Open";
            cp.LowData = "Low";
            cp.HighData = "High";
            cp.CloseData = "Close";
            cp.BearishColor = Color.Red;
            cp.BullishColor = Color.Green;
            cp.Style = NPlot.CandlePlot.Styles.Filled;

            cp.Label = this.dataItem.DataClass.Name;
          
            GetXMinXMax(cp);
            return cp;

            

        }
        /// <summary>
        /// Here is work to do ! Other charts plotted on (all) controls
        /// </summary>
        /// <returns></returns>
        private bool Plot_AdditionalShares()
        {
            //TODO!!!
            IList<string> listShares = IndicatorUtil.GetAdditionalDataItemsOnCharts(this.chartNumber, this.dataItem.Profile);
            if (listShares.Count > 0)
            {
                for (int i = 0; i < listShares.Count; i++)
                {
                    string strID = listShares[i];
                    IDataItem di = TradeEconomy.GetDataItemByID(strID);
                    if (di == null)
                    {
                        System.Windows.Forms.MessageBox.Show("The data to be shown was probably deleted - please delete this share from the Profile: " + strID);
                    }
                    else
                    {
                        //Debug.Assert(di != null, "DataItem not found - is the share deleted ?? " + strID);
                        Plot_ShareQuotes(di.DataClass, di.DataClass.QuoteCollection);
                    }
                }
            }
            return true;
        }
        private bool CheckAndResetQuotes()
        {
            this.plots = new ArrayList();
            quotes = null;
            //-----------------------------------------------------------
            //1. add quotes
            //quotes = this.dataItem.DataClass.QuoteCollection;
            quotes = this.dataItem.DataClass.QuotesChart(this.programContext.Configuration);

            //2. plot series, labels and grid
            if (quotes == null || quotes.Count < 1)
            {
                plotSurface.Title = "No data available for : " + this.dataItem.DataClass.Name;
                return false;
            }
            if (quotes.Count < 2)
                return false;

            return true;
        }
        private void SetTitleAndIndex()
        {
            if (this.indexStop == 0)
                this.indexStop = quotes.Count;

            this.plotChartQuotes = true;

            plotSurface.Title = this.dataItem.DataClass.Name + " : " +
                quotes[quotes.Count - 1].DATE.ToShortDateString() + "; "
                + quotes[quotes.Count - 1].CLOSEc.ToString();

        }
        public bool Plot_Control(bool intraday)
        {
            try
            {
                if (! CheckAndResetQuotes())
                {
                    return false;
                }
                else
                {
                    SetTitleAndIndex();
                    if(this.chartNumber == 0)
                        Plot_ShareQuotes(this.dataItem.DataClass, quotes);
                    
                    
                    this.programContext.Logfile.WriteTimeSpanLog("   after plot share  ");
                    if (! this.dataItem.HideIndicatorsOnChart)
                        Plot_Indicators();
                    
                    Plot_AdditionalShares();

                    //this.programContext.Logfile.WriteTimeSpanLog("   before legend  ");
                   
                }
                //this.programContext.Logfile.WriteTimeSpanLog("   before redraw ");
                return this.Redraw();


            }
            catch (Exception exc)
            {
                Debug.Assert(false, "Error in PlotChartQuote", exc.Message);
            }

            return false;
        }

        public void Plot_ShareQuotes(IDataClass myDataClass, IListQuotes myQuotes)
        {
            try
            {
                BasePlot bp = null;
                if (this.dataItem.ChartCandleStick)
                {
                    bp = this.Create_CandleStickPlot((System.Collections.IList)myQuotes);


                }
                else
                {
                    this.programContext.Logfile.WriteTimeSpanLog("    Plot Share: " + myDataClass.ID);
                    bp = this.Create_LinePlot(myDataClass.Name, (System.Collections.ICollection)myQuotes, false);


                }
                if (bp != null)
                    this.plots.Add(bp);
            }
            catch (Exception ex)
            {
                Debug.Assert(false, "Error in Plot_ShareQuotes " + ex.Message);
            }
        }

      
		
		public void SinglePrognosis(bool intraday, IIndicator ind)
		{
			ind.Prognosis_Advanced(ind.Values.Count - 1, intraday);

			IPrognosis progn = ind.Prognosis;
			//set the x - values
		
			int yValues = 100;
			ArrayList xColl = new ArrayList();
			ArrayList yColl = new ArrayList();


			//loop x - values
			for (int i = 0; i < progn.ExtrapolationInterval ; i++)
			{

				double xVal = (double)( ind.Values.Count + i);
				//loop 10 y values
				double yVal = progn.Alpha + progn.Beta * xVal;
				double yMax = (progn.Alpha + progn.AlphaError / progn.ExtrapolationInterval) + (progn.Beta + progn.BetaError/progn.ExtrapolationInterval) * xVal;
				double yMin = (progn.Alpha - progn.AlphaError/progn.ExtrapolationInterval) + (progn.Beta - progn.BetaError/progn.ExtrapolationInterval) * xVal;
				
				double stepYMin = (yVal - yMin)/yValues;
				double stepYMax = (yMax - yVal)/yValues;


				while(yVal > yMin)
				{
					xColl.Add(xVal );
					yColl.Add(yVal);
					yVal -= stepYMin;
				}
				yVal = progn.Alpha + progn.Beta * xVal;
				while(yVal < yMax)
				{
					xColl.Add(xVal );
					yColl.Add(yVal);
					yVal += stepYMax;
				}
			

			

			}
			double [] xs = new double [xColl.Count];
			double [] ys = new double [xColl.Count];


			for(int i = 0; i < xColl.Count; i++)
			{
				xs[i] = (double)xColl[i] ;
				ys[i] = (double)yColl[i] ;

				double val = ys[i];

				

			}

			Debug.Assert(false,"Prognosis TBD");

	
		}
		public void PlotPrognosis(bool intraday)
		{
			try
			{
				IIndicators indColl = null;
				//ArrayList indOnChart = null;
				if(intraday)
				{
					indColl = this.dataItem.DataClass.IndicatorsIntraday;
					
				}
				else
				{
					indColl = this.dataItem.DataClass.IndicatorsChecked;
					
				}
				
				for(int i = 0; i < indColl.Count; i++)
				{
					IIndicator ind = (IIndicator)indColl[i];



                    if (IndicatorUtil.GetIndicatorChartStatus(this.chartNumber, ind, this.dataItem.Profile))
					{
						
						SinglePrognosis(intraday, ind);
					}
				}
				
			}
			catch(Exception exc)
			{
				Debug.Assert(false,"Error plotting indicators intraday " + exc.Message);
			}
		}

        private int GetIndexOfQuote(IListQuotes quotes, TradeEvent te)
        {
            DateTime dt = te.Date;
            int ind = quotes.IndexOf(dt);

            if (this.Intraday)
            {
                Debug.Assert(ind >= 0, "Quote for date " + dt.ToShortTimeString() + " not found");
            }
            else
            {
                Debug.Assert(ind >= 0, "Quote for date " + dt.ToShortDateString() + " not found");
            }
            return ind;

        }
        private bool CreateTradeEventCollections_FromTradeSystem(ITradeStep ts, ArrayList buyCollectionX,
            ArrayList buyCollectionY, ArrayList sellCollectionX , 
                ArrayList sellCollectionY )

        {
            try
            {
                System.Collections.ArrayList tradeEvents = ts.TradeEvents;
                if (tradeEvents == null)
                {
                    System.Windows.Forms.MessageBox.Show("No trade events available - pls. run trade simulation first");
                    return false;
                }
                for (int i = 0; i < tradeEvents.Count; i++)
                {
                    TradeEvent te = tradeEvents[i] as TradeEvent;
                    if (te.ShareID == this.dataItem.DataClass.ID)
                    {
                        
                        int ind = GetIndexOfQuote(quotes, te);
                       
                        if (ind > 0)
                        {
                            //Point p = new Point(ind, quotes[ind].CLOSEc);

                            string strBuySell = te.TradeType.ToString();
                            if(strBuySell.Contains("Buy"))
                            {
                                buyCollectionX.Add(ind);
                                buyCollectionY.Add(quotes[ind].CLOSEc);
                            }
                            if (strBuySell.Contains("Sell"))
                            {
                                sellCollectionX.Add(ind);
                                sellCollectionY.Add(quotes[ind].CLOSEc);
                            }
                            //switch (te.TradeType)
                            //{
                            //    //case (TradeType.Buy):
                            //    //    {
                            //    //        buyCollectionX.Add(ind);
                            //    //        buyCollectionY.Add(quotes[ind].CLOSEc);


                            //    //        //ys[ind] = quotes[ind].CLOSEc;
                            //    //        break;
                            //    //    }
                            //    //case (TradeType.Buy10000):
                            //    //    {
                            //    //        buyCollectionX.Add(ind);
                            //    //        buyCollectionY.Add(quotes[ind].CLOSEc);
                            //    //        //ys[ind] = quotes[ind].CLOSEc;
                            //    //        break;
                            //    //    }
                            //    //case (TradeType.Buy10000Again):
                            //    //    {
                            //    //        buyCollectionX.Add(ind);
                            //    //        buyCollectionY.Add(quotes[ind].CLOSEc);
                            //    //        //ys[ind] = quotes[ind].CLOSEc;
                            //    //        break;
                            //    //    }
                            //    //case (TradeType.BuyOneShare):
                            //    //    {
                            //    //        buyCollectionX.Add(ind);
                            //    //        buyCollectionY.Add(quotes[ind].CLOSEc);
                            //    //        //ys[ind] = quotes[ind].CLOSEc;
                            //    //        break;
                            //    //    }
                            //    //case (TradeType.BuyShort):
                            //    //    {
                            //    //        buyCollectionX.Add(ind);
                            //    //        buyCollectionY.Add(quotes[ind].CLOSEc);
                            //    //        //ys[ind] = quotes[ind].CLOSEc;
                            //    //        break;
                            //    //    }
                            //    //case (TradeType.BuyStopLoss):
                            //    //    {
                            //    //        buyCollectionX.Add(ind);
                            //    //        buyCollectionY.Add(quotes[ind].CLOSEc);
                            //    //        //ys[ind] = quotes[ind].CLOSEc;
                            //    //        break;
                            //    //    }
                            //    //case (TradeType.BuyStopWin):
                            //    //    {
                            //    //        buyCollectionX.Add(ind);
                            //    //        buyCollectionY.Add(quotes[ind].CLOSEc);
                            //    //        //ys[ind] = quotes[ind].CLOSEc;
                            //    //        break;
                            //    //    }



                            //    case (TradeType.Sell):
                            //        {
                            //            sellCollectionX.Add(ind);
                            //            sellCollectionY.Add(quotes[ind].CLOSEc);
                            //            //zs[ind] = quotes[ind].CLOSEc;
                            //            break;
                            //        }
                            //    case (TradeType.SellShort10000):
                            //        {
                            //            sellCollectionX.Add(ind);
                            //            sellCollectionY.Add(quotes[ind].CLOSEc);
                            //            //zs[ind] = quotes[ind].CLOSEc;
                            //            break;
                            //        }
                            //    case (TradeType.SellShort10000Again):
                            //        {
                            //            sellCollectionX.Add(ind);
                            //            sellCollectionY.Add(quotes[ind].CLOSEc);
                            //            //zs[ind] = quotes[ind].CLOSEc;
                            //            break;
                            //        }
                            //    case (TradeType.SellStopLoss):
                            //        {
                            //            sellCollectionX.Add(ind);
                            //            sellCollectionY.Add(quotes[ind].CLOSEc);
                            //            //zs[ind] = quotes[ind].CLOSEc;
                            //            break;
                            //        }
                            //    case (TradeType.SellStopDynamic):
                            //        {
                            //            sellCollectionX.Add(ind);
                            //            sellCollectionY.Add(quotes[ind].CLOSEc);
                            //            //zs[ind] = quotes[ind].CLOSEc;
                            //            break;
                            //        }
                            //    case (TradeType.SellStopWin):
                            //        {
                            //            sellCollectionX.Add(ind);
                            //            sellCollectionY.Add(quotes[ind].CLOSEc);
                            //            //zs[ind] = quotes[ind].CLOSEc;
                            //            break;
                            //        }
                            //}
                        }

                    }
                }
                return true;
            }
            catch (Exception ex)
            {
                Debug.Assert(false, "Error creating TradeEvents: " + ex.Message);
                return false;
            }
        }


        private bool DoInitialChecks(IProgramContext dH, out IDataItem di, out ITradeStep ts)
        {
            di = this.dataItem.DataClass.Parent as DataItem;
            ts = null;
            if (di == null)
            {
                System.Windows.Forms.MessageBox.Show("Please perform a trade simulation first ");
                return false;
            }
            quotes = this.dataItem.DataClass.QuotesChart(this.programContext.Configuration);
            this.programContext = dH;
            ts = di.TradeStep;
            if (ts == null)
            {
                System.Windows.Forms.MessageBox.Show("No trade system evaluations done for this share");
                return false;

            }
            return true;
        }
        private bool CreateTradeCollections(ITradeStep ts, out  DateTime[] xs, out double[] ys, bool buyOrSell)
        {
            xs = null;
            ys = null;

            ArrayList buyCollectionX = new ArrayList();
            ArrayList buyCollectionY = new ArrayList();
            ArrayList sellCollectionX = new ArrayList();
            ArrayList sellCollectionY = new ArrayList();

            if (!CreateTradeEventCollections_FromTradeSystem(ts, buyCollectionX, buyCollectionY, sellCollectionX, sellCollectionY))
            {
                return false;
            }

            if (buyCollectionX.Count < 1 && sellCollectionX.Count < 1)
            {
                System.Windows.Forms.MessageBox.Show("No trade events for this share");
                return false;
            }

            if(buyOrSell)
                CreateArrayFromCollection(ref xs, ref ys, buyCollectionX, buyCollectionY);
            else
                CreateArrayFromCollection(ref xs, ref ys, sellCollectionX, sellCollectionY);

            return true;

        }
		public bool PlotEvents(bool show, bool intraday, IProgramContext dH)
		{
            try
            {
                IDataItem di = null;
                ITradeStep ts;
                if (!DoInitialChecks(dH, out di, out ts))
                    return false;

                if (show)
                {
                    DateTime[] xs = null;
                    double[] ys = null;
                    CreateTradeCollections(ts, out xs, out ys, true);
                    Marker m;
                    PointPlot pp;
                    if (xs.GetLength(0) > 0)
                    {
                        //Debug.Assert(false, "TBD");

                        //buy events
                        m = new Marker(Marker.MarkerType.Triangle, 6, new Pen(Color.Green, penWidthMarker));
                        pp = new PointPlot();
                        pp.OrdinateData = ys;
                        pp.AbscissaData = xs;
                        pp.Marker = m;
                        pp.Label = "Buy Events";
                        plotSurface.Add(pp);


                        this.plots.Add(pp);
                    }

                    //Sell events
                  
                    CreateTradeCollections(ts, out xs, out ys, false);
                    if (xs.GetLength(0) > 0)
                    {
                        m = new Marker(Marker.MarkerType.Cross1, 6, new Pen(Color.Red, penWidthMarker));
                        pp = new PointPlot();
                        pp.OrdinateData = ys;
                        pp.AbscissaData = xs;
                        pp.Marker = m;
                        pp.Label = pp.Label = "Sell Events";
                        plotSurface.Add(pp);


                        this.plots.Add(pp);

                    }
                    plotSurface.Refresh();
                }
                else
                {
                    for (int i = plots.Count - 1; i > -1; i--)
                    {

                        IPlot ipl = this.plots[i] as IPlot;
                        if (ipl.Label == "Sell Events" || ipl.Label == "Buy Events")

                            this.plots.Remove(ipl);
                        RefreshQuotes();
                        Plot_Indicators();

                        Redraw();

                    }
                }
                plotSurface.Refresh();
                return true;
            }
            catch (Exception ex)
            {
                Debug.Assert(false, "Error in PlotEvents: " + ex.Message);
                return false;
            }

		}
		private void CreateArrayFromCollection(ref DateTime [] xs, ref double [] ys, ArrayList collX, ArrayList collY )
		{
			//xs = new double [collX.Count];
            xs = new DateTime[collX.Count];

			ys = new double [collY.Count];
			for(int i = 0; i < collX.Count; i++)
			{
				int indexQuote = (int)collX[i];
                xs[i] = this.quotes[indexQuote].DATE;
				ys[i] = Convert.ToDouble(collY[i]);

			}
		}
		private void ResetLimits()
		{
            //this.yMin = 1000000;
            //this.yMax = -1000; 
		}
     


        public bool ScrollPlot()
        {
            int size = this.indexStop - this.indexStart;

            ResetLimits();

            if (size > 0)
            {
                //Debug.Assert(plotSurface.XAxis1 != null, "Plot axis destroyed - software error");
                if (plotSurface.XAxis1 != null)
                {
                    plotSurface.XAxis1.WorldMin = ((DateTime)this.xValues[this.indexStart]).Ticks;
                    plotSurface.XAxis1.WorldMax = ((DateTime)this.xValues[this.indexStop - 1]).Ticks;
                }
               
                plotSurface.Refresh();
                return true;
            }

            return true;
        }

		private IIndicators GetIndicatorCollection()
		{

			IIndicators indColl = null;
			//ArrayList indOnChart = null;
			if(this.programContext.Configuration.IntradayModus)
			{
				indColl = this.DataItem.DataClass.IndicatorsIntraday;
				
            }
			else
			{
				indColl = this.DataItem.DataClass.IndicatorsChecked;
				
			}
			return indColl;
		}
		private void CheckIndicator(IIndicator ind)
		{
            //Debug.Assert(this.Quotes != null, "Quotes not set when trying to plot");
			IList<double> items1 = ind.ValuesFloat;

            if (IndicatorUtil.GetIndicatorChartStatus(this.chartNumber, ind, this.dataItem.Profile))
			{
				//Check if the indicator is up to date
                if (items1.Count != this.dataItem.DataClass.QuoteCollection.Count)
				{
                    if (this.dataItem.DataClass.QuoteCollection == null)
					{
						if(this.programContext.Configuration.IntradayModus)
						{
							//refresh indicator every time
                            ind = ind.Get_FromXML_OrRecalc();
                            this.dataItem.DataClass.DeSerialize_IntradayPart();
						
						}
						else
						{
							object o = this.dataItem.DataClass;
							this.dataItem.DataClass.DeSerialize(ref o);
						
						}
					}
					else
					{
						if(this.programContext.Configuration.IntradayModus)
						{
							//refresh indicator every time
                            ind = ind.Get_FromXML_OrRecalc();
                            this.dataItem.DataClass.DeSerialize_IntradayPart();						
						}
						
					}
				
				}
			}
		}
		public void AddIndicator(IIndicator ind)
		{
            if (!this.dataItem.DataClass.IndicatorsJustGetEm.Contains(ind))
            {
                this.dataItem.DataClass.IndicatorsJustGetEm.Add(ind);
                Create_IndicatorPlot(ind, true);
            }
           
			
		}
      
		private void Create_IndicatorPlot(IIndicator ind, bool checkIndicator)
		{
            if(checkIndicator)
                this.CheckIndicator(ind);
            //check if already there...
            for (int i = 0; i < plots.Count; i++)
            {
                IPlot ipl = this.plots[i] as IPlot;
                
                if (ipl.Label == ind.Name)
                    return;

            }
			try
			{
				IHistorical hist = ind as IHistorical;
				if(hist != null)
				{
                    ind = ind.Get_FromXML_OrRecalc();
					for(int j = 0; j < hist.ResultCollection.Count; j++)
					{
                        LinePlot lp = this.Create_LinePlot(hist as IIndicator);
                        lp.Label = ind.Name;
                        this.plots.Add(lp);
                        
					}
											
				}
				else
				{
                    LinePlot lp = this.Create_LinePlot(ind);
                    lp.Label = ind.Name;
                    
                    this.plots.Add(lp);

				}
										
			}
			
			catch(Exception exc)
			{
				Debug.Assert(false,"Error plotting single indicator " + ind.Name, exc.Message);
			}
		}
        private void Remove_OtherSharePlots(string myID)
        {



            for (int i = plots.Count - 1; i > -1; i--)
            {
                //bool bfound = false;
                IPlot ipl = this.plots[i] as IPlot;
                if (ipl.Label == myID)
                {
                     this.plots.Remove(ipl);
                  
                }
               // if (bfound)
                   
            }

        }
        private void Remove_IndicatorPlots()
        {

           

            for (int i = plots.Count - 1; i > -1; i--)
            {
                bool bfound = false;
                IPlot ipl = this.plots[i] as IPlot;
                if (ipl.Label != this.dataItem.DataClass.Name)
                {
                    
                    for (int j = 0; j < this.dataItem.DataClass.IndicatorsJustGetEm.Count; j++)
                    {
                        IIndicator ind = this.dataItem.DataClass.IndicatorsJustGetEm[j] as IIndicator;
                        if (!IndicatorUtil.GetIndicatorChartStatus(this.chartNumber, ind, this.dataItem.Profile))
                        {
                            if (ipl.Label == ind.Name)
                            {

                                bfound = true;
                                break;
                            }
                        }




                    }
                }
                if(bfound)
                    this.plots.Remove(ipl);
            }
            
        }
		private void RefreshQuotes()
		{
			int indStop = this.IndexStop;
			int indStart = this.IndexStart;

		
          
			this.IndexStop = indStop;
			this.IndexStart = indStart;
			this.ScrollPlot();
		}


        private bool CheckIndicators()
        {
            if (this.dataItem.DataClass.IndicatorsJustGetEm.Count == 0)
            {
                //this.programContext.Logfile.WriteTimeSpanLog("   before getting inds");
                IIndicators inds = this.dataItem.DataClass.IndicatorsChecked;
                //this.programContext.Logfile.WriteTimeSpanLog("   after getting inds");


            }
            return true;

        }
        private bool Plot_Indicators()
        {
            try
            {
                this.dataItem.DataClass.ComputeIndicators_Profile(this.dataItem.Profile);
                //CheckIndicators();
              
                for (int i = 0; i < this.dataItem.DataClass.IndicatorsJustGetEm.Count; i++)
                {
                    IIndicator ind = (IIndicator)this.dataItem.DataClass.IndicatorsJustGetEm[i];

                    if (IndicatorUtil.GetIndicatorChartStatus(this.chartNumber, ind, this.dataItem.Profile))
                    {
                        ind.ShowOnChartNumber = this.chartNumber;
                        this.Create_IndicatorPlot(ind, false);
                        this.programContext.Logfile.WriteTimeSpanLog("   Create plot for: " + ind.Name);

                    }
                }
                return true;


            }
            catch (Exception exc)
            {
                Debug.Assert(false, "Error plotting indicators intraday " + exc.Message);
                return false;
            }
        }
     
      
        public bool RefreshChart()
        {
            try
            {
                Remove_IndicatorPlots();

                RefreshQuotes();
                this.Plot_Indicators();

                return Redraw();

            }
            catch (Exception ex)
            {
                Debug.Assert(false, "Error at Refresh_ChartLine" + ex.Message);
                return false;
            }
        }

   
        private void contextMenuProfile_Click(object sender, System.EventArgs e)
        {
            DialogProfile dp = new DialogProfile(this.dataItem);
            if (dp.ShowDialog() == DialogResult.OK)
            {                
                this.ChartWindow.RefreshWindow(false);
               
            }

        }
       
    }
}
